package cn.edu.scau.cmi.dengshixin.client;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.context.ApplicationContext;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import cn.edu.scau.cmi.dengshixin.interProgramming.*;
import cn.edu.scau.cmi.dengshixin.singleton.*;
import cn.edu.scau.cmi.dengshixin.mutipleton.*;
import cn.edu.scau.cmi.dengshixin.orm.dao.StudentDao;
import cn.edu.scau.cmi.dengshixin.orm.dao.TeacherDao;
import cn.edu.scau.cmi.dengshixin.factory.simpleFactory.*;
import cn.edu.scau.cmi.dengshixin.factory.normalFactory.*;
import cn.edu.scau.cmi.dengshixin.orm.spring.ApplicationContextUtil;
import cn.edu.scau.cmi.dengshixin.adapter.Student;
import cn.edu.scau.cmi.dengshixin.adapter.classAdapter.ClassAdapter;
import cn.edu.scau.cmi.dengshixin.adapter.objectAdapter.ObjectAdapter;
import cn.edu.scau.cmi.dengshixin.composite.Component;
import cn.edu.scau.cmi.dengshixin.composite.safe.SafeComposite;
import cn.edu.scau.cmi.dengshixin.composite.safe.SafePerson;
import cn.edu.scau.cmi.dengshixin.factory.abstractFactory.*;
import cn.edu.scau.cmi.dengshixin.factory.domain.*;
import cn.edu.scau.cmi.dengshixin.orm.hibernate.SessionFactoryUtil;
import cn.edu.scau.cmi.dengshixin.orm.domain.*;


public class Controller {

	@FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    
    //Button
    @FXML
    private Button ex0_Btn1;

    @FXML
    private Button ex0_Btn2;

    @FXML
    private Button ex1_AddBtn2;

    @FXML
    private Button ex1_AddBtn1;
    
    @FXML
    private Button ex3_CookBtn;
    
    @FXML
    private Button ex4_CookBtn;
    
    @FXML
    private Button ex5_CookBtn;
    
    @FXML
    private Button ex6_AddBtn;
    
    @FXML
    private Button ex7_AddOrgBtn;
    
    @FXML
    private Button ex7_AddPersonBtn;
    
    @FXML
    private Button ex7_DoBtn;
    
    @FXML
    private Button ex8_AddTeaBtn;
    
    @FXML
    private Button ex8_AddStuBtn;
    
    @FXML
    private Button ex8_ShowBtn;

    
    //TextArea
    @FXML
    private TextArea ex0_TextArea;
    
    @FXML
    private TextArea ex1_TextArea1;

    @FXML
    private TextArea ex1_TextArea2;
    
    @FXML
    private TextArea ex3_TextArea;
    
    @FXML
    private TextArea ex4_TextArea;
    
    @FXML
    private TextArea ex5_TextArea;
    
    @FXML
    private TextArea ex7_TextArea;
    
    @FXML
    private TextArea ex8_TextArea;
    
    
    //TextField
    @FXML
    private TextField ex1_TextField1;

    @FXML
    private TextField ex1_TextField2;
    
    @FXML
    private TextField ex6_TextField1;

    @FXML
    private TextField ex6_TextField2;
    
    @FXML
    private TextField ex7_TextField1;

    @FXML
    private TextField ex7_TextField2;
    
    @FXML
    private TextField ex8_TextField1;

    @FXML
    private TextField ex8_TextField2;
    
    @FXML
    private TextField ex8_TextField3;

    @FXML
    private TextField ex8_TextField4;

    
    
    //ComboBox
    @FXML
    private ComboBox<String> ex3_ComboBox;
    
    @FXML
    private ComboBox<String> ex4_ComboBox;
    
    @FXML
    private ComboBox<String> ex5_ComboBox1;
    
    @FXML
    private ComboBox<String> ex5_ComboBox2;
    
    @FXML
    private ComboBox<String> ex7_ComboBox1;
    
    @FXML
    private ComboBox<String> ex7_ComboBox2;
    
    @FXML
    private ComboBox<String> ex8_ComboBox;
    
    
    //TableView
    @FXML
    private TableView<Student> ex6_Table;
    
    
    //TableColumn
    @FXML
    private TableColumn<cn.edu.scau.cmi.dengshixin.adapter.Student, Integer> ex6_IdCol;

    @FXML
    private TableColumn<cn.edu.scau.cmi.dengshixin.adapter.Student, String> ex6_NameCol;
    

    @FXML
    void learn1(ActionEvent event) {
    	//大学生的learn
    	UndergraduateStudent ugStudent = new UndergraduateStudent();
    	ex0_TextArea.appendText(ugStudent.learn());
    }

    @FXML
    void learn2(ActionEvent event) {
    	//研究生的learn
    	GraduateStudent gStudent = new GraduateStudent();
    	ex0_TextArea.appendText(gStudent.learn());
    }
    
    @FXML
    void ex1AddChairman(ActionEvent event) {
    	String input = ex1_TextField1.getText();
    	ex1_TextField1.clear();
    	Chairman chairman;
    	if(input.equals("")) {
    		chairman = Chairman.getInstance();
    		if(chairman == null) {
    			ex1_TextArea1.appendText("请输入主席名！\n");
    		}
    		else {
    			ex1_TextArea1.appendText(chairman.getName() + chairman + "\n");
    		}
    	}
    	else {
    		chairman = Chairman.getInstance(input);
    		ex1_TextArea1.appendText(chairman.getName() + chairman + "\n");
    	}
    }

    @FXML
    void ex1AddMarshal(ActionEvent event) {
    	String input = ex1_TextField2.getText();
    	ex1_TextField2.clear();
    	Marshal marshal;
    	if(input.equals("")) {
    		ex1_TextArea2.appendText("请输入元帅名！\n");
    	}
    	else {
    		marshal = Marshal.getInstance(input);
    		if(marshal != null) {
    			ex1_TextArea2.appendText(marshal.getName() + marshal + "\n");
    		}
    		else {
    			ex1_TextArea2.appendText("你已经创建" + Marshal.count +  "个元帅了！\n");
    		}
    		
    	}
    }
    
    @FXML
    void ex3Produce(ActionEvent event) {
    	//简单工厂模式
    	SimpleFactory factory = new SimpleFactory();
    	String meatName = null;
    	try {
    		meatName = ex3_ComboBox.getSelectionModel().getSelectedItem().toString();
    	}
    	catch(Exception e) {
    		meatName = "";
    	}
    	Meat meat = factory.produce(meatName);
    	if(meat == null) {
    		ex3_TextArea.appendText("请选择肉类！\n");
    	}
    	else {
    		ex3_TextArea.appendText(factory.produce(meatName).cook());
    	}
    }
    
    @FXML
    void ex4Produce(ActionEvent event) {
    	//工厂模式
    	String meatName = null;
    	try {
    		meatName = ex4_ComboBox.getSelectionModel().getSelectedItem().toString();
    	}
    	catch(Exception e) {
    		meatName = "";
    	}
    	NormalFactory factory = null;
    	switch(meatName) {
		case "猪肉":
			factory = new PorkFactory();
			break;
		case "鸡肉":
			factory = new ChickenFactory();
			break;
		case "牛肉":
			factory = new BeafFactory();
			break;
		}
    	if(factory == null) {
    		ex4_TextArea.appendText("请选择肉类！\n");
    	}
    	else {
    		ex4_TextArea.appendText(factory.produce().cook());
    	}
    }
    
    @FXML
    void ex5Produce(ActionEvent event) {
    	//抽象工厂模式
    	String brandName = null;
    	String meatName = null;
    	try {
    		brandName = ex5_ComboBox1.getSelectionModel().getSelectedItem().toString();
    	}
    	catch(Exception e) {
    		brandName = "";
    	}
    	try {
    		meatName = ex5_ComboBox2.getSelectionModel().getSelectedItem().toString();
    	}
    	catch(Exception e) {
    		meatName = "";
    	}
    	AbstractFactory factory = null;
    	switch(brandName) {
    	case "温氏":
    		factory = new WensMeatFactory();
    		break;
    	case "傲农":
    		factory = new AonongMeatFactory();
    		break;
    	case "天邦":
    		factory = new TianbangMeatFactory();
    		break;
    	}
    	if(factory == null) {
    		ex5_TextArea.appendText("请选择品牌！\n");
    		return;
    	}
    	Meat meat = null;
    	meat = factory.produce(meatName);
    	if(meat == null) {
    		ex5_TextArea.appendText("请选择肉类！\n");
    		return;
    	}
    	ex5_TextArea.appendText(meat.cook());
    }
    
    static private ArrayList<cn.edu.scau.cmi.dengshixin.adapter.Student> studentList;
    static private ObservableList<cn.edu.scau.cmi.dengshixin.adapter.Student> data;
    @FXML
    void ex6Sort(ActionEvent event) {
    	if(studentList == null) {
    		studentList = new ArrayList<Student>();
    		//data = FXCollections.observableArrayList();
    	}
    	data = FXCollections.observableArrayList();
    	ex6_IdCol.setCellValueFactory(new PropertyValueFactory<Student, Integer>("id"));
    	ex6_NameCol.setCellValueFactory(new PropertyValueFactory<Student, String>("name"));
    	
    	String idInput, nameInput;
    	idInput = ex6_TextField1.getText();
    	nameInput = ex6_TextField2.getText();
    	if(idInput.equals("") || nameInput.equals("")) return;
    	ex6_TextField1.clear();
    	ex6_TextField2.clear();
    	
    	Integer id = new Integer(idInput);
    	String name = nameInput;
    	Student student = (cn.edu.scau.cmi.dengshixin.adapter.Student) new Student(name, id);
    	studentList.add(student);
    	
    	//ClassAdapter sort = new ClassAdapter();	//类适配器
    	ObjectAdapter sort  = new ObjectAdapter();	//对象适配器
    	sort.sortStudent(studentList);
    	for(Student s : studentList) {
    		data.add(s);
    	}
    	ex6_Table.setItems(data);
    }
    
    
    static private ObservableList<String> orgList = FXCollections.observableArrayList();
    ArrayList<Component> departments = new ArrayList<Component>();
    @FXML
    void ex7AddOrg(ActionEvent event) {
    	String dept = null;
    	String superDept = null;
    	SafeComposite department = null;
    	dept = ex7_TextField1.getText();
    	if(dept.equals("")) {
    		ex7_TextArea.appendText("请输入新部门名！\n");
    	}
    	else {
    		try {
    			superDept = ex7_ComboBox1.getSelectionModel().getSelectedItem().toString();
    		}
        	catch(Exception e) { }
			boolean flag = true;
    		for(String str : orgList) {
    			if(str.equals(dept)) {
    				ex7_TextArea.appendText("部门已存在！\n");
    				flag = false;
    				break;
    			}
    		}
    		if(flag) {
    			//有新部门要添加
    			department = new SafeComposite(dept, superDept);
    			if(superDept != null) {
    				//如果新部门隶属于某个部门，则要找到那个父部门的节点
    				for(Component c : departments) {
    					if(c.getName().equals(superDept)) {
    						c.addChild(department);
    						break;
    					}
    				}
    			}
    			departments.add(department);
    			orgList.add(dept);
    			ex7_TextArea.appendText("添加部门成功！\n");
    		}
    	}
    	ex7_TextField1.clear();
    }
    
    @FXML
    void ex7AddPerson(ActionEvent event) {
    	String name = ex7_TextField2.getText();
    	String dept = null;
    	SafePerson person = null;
    	if(name.equals("")) {
    		ex7_TextArea.appendText("请输入员工名！\n");
    	}
    	else {
    		try {
    			dept = ex7_ComboBox2.getSelectionModel().getSelectedItem().toString();
    		}
        	catch(Exception e) {
        		ex7_TextArea.appendText("请选择部门！\n");
        		return;
        	}
    		person = new SafePerson(name, dept);
    		for(Component c : departments) {
				if(c.getName().equals(dept)) {
					c.addChild(person);
					ex7_TextArea.appendText("添加员工成功！\n");
					break;
				}
			}
    		ex8_TextField1.clear();
    	}
    }
    
    @FXML
    void ex7DoSomething(ActionEvent event) {
    	if(departments.isEmpty()) {
    		ex7_TextArea.appendText("并没有什么部门和员工！\n");
    		return;
    	}
    	boolean flag = false;
    	for(Component c : departments) {
    		flag = false;
    		for(Component cc : departments) {
    			if(cc.getName().equals(c.getOrganization())) {
    				flag = true;
    			}
    		}
    		if(flag) continue;
    		c.doSomething(ex7_TextArea);
    	}
    }
    
    static private ObservableList<String> teaList = FXCollections.observableArrayList();
    @FXML
    void ex8addTea(ActionEvent event) {
    	String t_name = null;
    	String t_id = null;
    	t_name = ex8_TextField1.getText();
    	t_id = ex8_TextField2.getText();
    	if(t_id.equals("") || t_name.equals("")) {
    		ex8_TextArea.appendText("请输入完整的教师信息！\n");
    	}
    	Long id = Long.parseLong(t_id);
    	Session session = SessionFactoryUtil.getSession();
		Transaction transaction = session.beginTransaction();
		
    	Teacher tea = new Teacher();
    	tea.setId(id);
    	tea.setName(t_name);
    	
    	ApplicationContext ac = ApplicationContextUtil.getApplicationContext();
		TeacherDao teacherDao=(TeacherDao) ac.getBean("teacherDao");
		try {
			teacherDao.save(tea);
		}
		catch(RuntimeException re) {
			ex8_TextArea.appendText("添加教师失败！\n");
			throw re;
		}
		finally {
			ex8_TextField1.clear();
			ex8_TextField2.clear();
		}
		teaList.add(t_name);
		ex8_TextArea.appendText("添加教师成功！\n");
		transaction.commit();
		session.close();
    }
    
    @FXML
    void ex8addStu(ActionEvent event) {
    	String s_name = null;
    	String s_id = null;
    	String t_name = null;
    	s_name = ex8_TextField3.getText();
    	s_id = ex8_TextField4.getText();
    	if(s_id.equals("") || s_name.equals("")) {
    		ex8_TextArea.appendText("请输入完整的学生信息！\n");
    		return;
    	}
    	try {
    		t_name = ex8_ComboBox.getSelectionModel().getSelectedItem().toString();
		}
    	catch(Exception e) {
    		ex8_TextArea.appendText("请选择指导老师！\n");
    		throw e;
    	}
    	Long id = Long.parseLong(s_id);
    	Session session = SessionFactoryUtil.getSession();
		Transaction transaction = session.beginTransaction();
    	
    	cn.edu.scau.cmi.dengshixin.orm.domain.Student stu = new cn.edu.scau.cmi.dengshixin.orm.domain.Student();
    	stu.setId(id);
    	stu.setName(s_name);
    	
    	ApplicationContext ac = ApplicationContextUtil.getApplicationContext();
		TeacherDao teacherDao=(TeacherDao) ac.getBean("teacherDao");
		StudentDao studentDao=(StudentDao) ac.getBean("studentDao");
		
		List<Teacher> list = teacherDao.findByName(t_name);
		Teacher tea = list.get(0);
		stu.setTeacher(tea);
		try {
			studentDao.save(stu);
		}
		catch(RuntimeException re) {
			ex8_TextArea.appendText("添加学生失败！\n");
			throw re;
		}
		finally {
			ex8_TextField3.clear();
			ex8_TextField4.clear();
		}
		ex8_TextArea.appendText("添加学生成功！\n");
		transaction.commit();
		session.close();
	}
    
    @FXML
    void ex8show(ActionEvent event) {
    	ApplicationContext ac = ApplicationContextUtil.getApplicationContext();
		StudentDao studentDao=(StudentDao) ac.getBean("studentDao");
		List<cn.edu.scau.cmi.dengshixin.orm.domain.Student> list = studentDao.findAll();
		for(cn.edu.scau.cmi.dengshixin.orm.domain.Student stu : list) {
			ex8_TextArea.appendText("\n学号：" + stu.getId() + "\n姓名：" + stu.getName() + 
					"\n指导老师工号：" + stu.getTeacher().getName() + "\n指导老师姓名：" + stu.getTeacher().getId() + "\n\n");
		}
    }
    
    @FXML
    void initialize() {
    	assert ex4_TextArea != null : "fx:id=\"ex4_TextArea\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex7_TextArea != null : "fx:id=\"ex7_TextArea\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex6_IdCol != null : "fx:id=\"ex6_IdCol\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_ShowBtn != null : "fx:id=\"ex8_ShowBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex7_DoBtn != null : "fx:id=\"ex7_DoBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex1_TextField1 != null : "fx:id=\"ex1_TextField1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex7_TextField1 != null : "fx:id=\"ex7_TextField1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_TextField4 != null : "fx:id=\"ex8_TextField4\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_TextField3 != null : "fx:id=\"ex8_TextField3\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex1_TextField2 != null : "fx:id=\"ex1_TextField2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_ComboBox != null : "fx:id=\"ex8_ComboBox\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex0_Btn1 != null : "fx:id=\"ex0_Btn1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex5_TextArea != null : "fx:id=\"ex5_TextArea\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex6_Table != null : "fx:id=\"ex6_Table\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex3_ComboBox != null : "fx:id=\"ex3_ComboBox\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex7_AddPersonBtn != null : "fx:id=\"ex7_AddPersonBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex0_Btn2 != null : "fx:id=\"ex0_Btn2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex1_AddBtn2 != null : "fx:id=\"ex1_AddBtn2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex7_ComboBox1 != null : "fx:id=\"ex7_ComboBox1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex1_AddBtn1 != null : "fx:id=\"ex1_AddBtn1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex7_ComboBox2 != null : "fx:id=\"ex7_ComboBox2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex6_AddBtn != null : "fx:id=\"ex6_AddBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex4_CookBtn != null : "fx:id=\"ex4_CookBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex5_ComboBox2 != null : "fx:id=\"ex5_ComboBox2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_AddTeaBtn != null : "fx:id=\"ex8_AddTeaBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex1_TextArea1 != null : "fx:id=\"ex1_TextArea1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex6_TextField1 != null : "fx:id=\"ex6_TextField1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex1_TextArea2 != null : "fx:id=\"ex1_TextArea2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex3_CookBtn != null : "fx:id=\"ex3_CookBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex6_TextField2 != null : "fx:id=\"ex6_TextField2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex3_TextArea != null : "fx:id=\"ex3_TextArea\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_TextArea != null : "fx:id=\"ex8_TextArea\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex5_CookBtn != null : "fx:id=\"ex5_CookBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex5_ComboBox1 != null : "fx:id=\"ex5_ComboBox1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex4_ComboBox != null : "fx:id=\"ex4_ComboBox\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex0_TextArea != null : "fx:id=\"ex0_TextArea\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_AddStuBtn != null : "fx:id=\"ex8_AddStuBtn\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_TextField2 != null : "fx:id=\"ex8_TextField2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex7_TextField2 != null : "fx:id=\"ex7_TextField2\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex8_TextField1 != null : "fx:id=\"ex8_TextField1\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex6_NameCol != null : "fx:id=\"ex6_NameCol\" was not injected: check your FXML file 'GUI.fxml'.";
        assert ex7_AddOrgBtn != null : "fx:id=\"ex7_AddOrgBtn\" was not injected: check your FXML file 'GUI.fxml'.";

        
        //工厂模式初始化
        List<String> meatList = Arrays.asList("猪肉", "鸡肉", "牛肉");
    	ObservableList<String> obList = FXCollections.observableArrayList(meatList);
    	ex3_ComboBox.setItems(obList); // 设置下拉框的数据来源
    	ex4_ComboBox.setItems(obList);
    	ex5_ComboBox2.setItems(obList);
    	List<String> brandList = Arrays.asList("温氏", "傲农", "天邦");
    	obList = FXCollections.observableArrayList(brandList);
    	ex5_ComboBox1.setItems(obList);

    	ex7_ComboBox1.setItems(orgList);
    	ex7_ComboBox2.setItems(orgList);
    	
    	ApplicationContext ac = ApplicationContextUtil.getApplicationContext();
		TeacherDao teacherDao=(TeacherDao) ac.getBean("teacherDao");
		List<Teacher> list = teacherDao.findAll();
		for(Teacher tea : list) {
			teaList.add(tea.getName());
		}
    	ex8_ComboBox.setItems(teaList);
    }
}
